using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace WpfApp_ChenxiConsole.FileIO
{
    /// <summary>
    /// 文件信息类，保存已加载文件的详细信息
    /// </summary>
    public class LoadedFileInfo
    {
        public string FileName { get; set; } = string.Empty;
        public string FilePath { get; set; } = string.Empty;
        public long FileSize { get; set; }
        public string FileType { get; set; } = string.Empty;
        public DateTime LoadTime { get; set; }
        public byte[] FileContent { get; set; } = Array.Empty<byte>();
    }

    /// <summary>
    /// 文件加载器类，用于处理BIN和HEX文件的加载
    /// </summary>
    public class FileLoader
    {
        // 保存已加载文件的列表
        private List<LoadedFileInfo> _loadedFiles = new List<LoadedFileInfo>();

        /// <summary>
        /// 获取已加载文件的列表
        /// </summary>
        public List<LoadedFileInfo> LoadedFiles => _loadedFiles;

        /// <summary>
        /// 加载BIN文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns>文件内容的字节数组</returns>
        public byte[] LoadBinFile(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    throw new FileNotFoundException("文件不存在", filePath);
                }

                // 读取整个BIN文件内容
                byte[] content = File.ReadAllBytes(filePath);

                // 记录已加载的文件信息
                FileInfo fileInfo = new FileInfo(filePath);
                _loadedFiles.Add(new LoadedFileInfo
                {
                    FileName = fileInfo.Name,
                    FilePath = filePath,
                    FileSize = fileInfo.Length,
                    FileType = "BIN",
                    LoadTime = DateTime.Now,
                    FileContent = content
                });

                return content;
            }
            catch (Exception ex)
            {
                throw new Exception("加载BIN文件失败: " + ex.Message);
            }
        }

        /// <summary>
        /// 加载HEX文件并转换为字节数组
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns>解析后的字节数组</returns>
        public byte[] LoadHexFile(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    throw new FileNotFoundException("文件不存在", filePath);
                }

                List<byte> data = new List<byte>();
                string[] lines = File.ReadAllLines(filePath);

                foreach (string line in lines)
                {
                    // HEX文件每行以冒号开始
                    if (line.StartsWith(":"))
                    {
                        try
                        {
                            // 解析HEX记录
                            List<byte> recordData = ParseHexRecord(line);
                            data.AddRange(recordData);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("解析HEX记录失败: " + ex.Message);
                        }
                    }
                }

                byte[] content = data.ToArray();

                // 记录已加载的文件信息
                FileInfo fileInfo = new FileInfo(filePath);
                _loadedFiles.Add(new LoadedFileInfo
                {
                    FileName = fileInfo.Name,
                    FilePath = filePath,
                    FileSize = fileInfo.Length,
                    FileType = "HEX",
                    LoadTime = DateTime.Now,
                    FileContent = content
                });

                return content;
            }
            catch (Exception ex)
            {
                throw new Exception("加载HEX文件失败: " + ex.Message);
            }
        }

        /// <summary>
        /// 清除已加载文件的记录
        /// </summary>
        public void ClearLoadedFiles()
        {
            _loadedFiles.Clear();
        }

        /// <summary>
        /// 解析单个HEX记录
        /// </summary>
        /// <param name="record">HEX记录字符串</param>
        /// <returns>解析出的数据字节</returns>
        private List<byte> ParseHexRecord(string record)
        {
            List<byte> data = new List<byte>();

            // 检查记录格式是否正确
            if (string.IsNullOrEmpty(record) || !record.StartsWith(":"))
            {
                throw new FormatException("无效的HEX记录格式");
            }

            try
            {
                // 跳过冒号，获取数据部分
                string hexData = record.Substring(1);

                // 每条HEX记录至少需要11个字符（1字节长度 + 2字节地址 + 1字节类型 + n字节数据 + 1字节校验和）
                if (hexData.Length < 10 || hexData.Length % 2 != 0)
                {
                    throw new FormatException("HEX记录长度无效");
                }

                // 计算记录长度（字节数）
                int recordLength = hexData.Length / 2;
                byte[] recordBytes = new byte[recordLength];

                // 将HEX字符串转换为字节数组
                for (int i = 0; i < recordLength; i++)
                {
                    string hexByte = hexData.Substring(i * 2, 2);
                    recordBytes[i] = Convert.ToByte(hexByte, 16);
                }

                // 获取数据长度（第一个字节）
                int dataLength = recordBytes[0];

                // 获取记录类型（第四个字节）
                byte recordType = recordBytes[3];

                // 数据记录（类型00）包含实际数据
                if (recordType == 0x00)
                {
                    // 从第五个字节开始，读取指定长度的数据
                    for (int i = 0; i < dataLength; i++)
                    {
                        data.Add(recordBytes[4 + i]);
                    }
                }
                // 结束记录（类型01）不需要处理数据
                else if (recordType == 0x01)
                {
                    // 结束记录，不需要添加数据
                }
                // 其他类型的记录暂时不处理
                else
                {
                    // 可以根据需要添加对扩展线性地址记录（02）、扩展段地址记录（04）等的支持
                }
            }
            catch (Exception ex)
            {
                throw new FormatException("解析HEX记录失败: " + ex.Message);
            }

            return data;
        }
    }
}